#include <cassert>

#include <glm/glm.hpp>

#include "Terrain.hpp"

#include "Debug.hpp"

CTerrain::CTerrain(int length, int width, int heightMin, int heightMax) : length(length), width(width), heightMin(heightMin), heightMax(heightMax)
{
	assert(length >=2 && width >= 2);
	Generate();
}

CTerrain::~CTerrain()
{
}

void CTerrain::Generate()
{
	glm::vec3 lastCoord(0, 0, 0);

	terrain.reserve(length*width);

	TerrainVertex vert;

	int t = 0;
	for(int z = 0; z < length; ++z)
	{
		for(int x = 0; x < width; ++x)
		{
			if(t == 4)
				t = 0;
			if(t == 0)
			{
				vert.tx = 0.f;
				vert.ty = 1.f;
			}
			else if(t == 1)
			{
				vert.tx = 0.f;
				vert.ty = 0.f;
			}
			else if(t == 2)
			{
				vert.tx = 1.f;
				vert.ty = 0.f;
			}
			else if(t == 3)
			{
				vert.tx = 1.f;
				vert.ty = 1.f;
			}

			vert.x = 0;
			vert.y = 0;
			vert.z = 0;

			int randInt = rand() % 100;
			float diff = (float)(randInt) * 0.005f;

			if(randInt % 2 == 0)
			{
				vert.y += diff;
			}
			else if(randInt % 5 == 0)
			{
				vert.y += diff*2;
			}
	
			vert.x = (float)x;
			vert.z = (float)z;

			lastCoord.z = vert.z;
			lastCoord.x = vert.x;
			lastCoord.y = vert.y;

			if(z % 3 == 0)
			{
				vert.colour[0] = 0.f;
				vert.colour[1] = 0.f;
				vert.colour[2] = 1.f;
				vert.colour[3] = 1.f;
			}
			else if(z % 2 == 0)
			{
				vert.colour[0] = 1.f;
				vert.colour[1] = 0.f;
				vert.colour[2] = 0.f;
				vert.colour[3] = 1.f;
			}
			else
			{
				vert.colour[0] = 0.f;
				vert.colour[1] = 1.f;
				vert.colour[2] = 0.f;
				vert.colour[3] = 1.f;
			}
			terrain.push_back(vert);

			++t;
		}
	}

	for(int z = 0; z < length - 1; ++z)
	{
		if(z % 2 == 0)
		{
			int x = 0;
			for(; x < width; ++x)
			{
				indices.push_back(x + (z * length));
				indices.push_back(x + (z * length) + width);
			}

			if(z != length - 2)
			{
				indices.push_back(--x + (z * length));
			}
		}
		else
		{
			int x;
			for(x = width - 1; x >= 0; x--)
			{
				indices.push_back(x + (z * length));
				indices.push_back(x + (z * length) + width);
			}

			if(z != length - 2)
			{
				indices.push_back(++x + (z * length));
			}
		}
	}
}

std::vector<TerrainVertex>& CTerrain::GetTerrain()
{
	return terrain;
}

std::vector<GLuint>& CTerrain::GetIndices()
{
	return indices;
}
